package com.siao.data
{
	
	import com.siao.utils.json.Json;
	
	import flash.utils.describeType;
	
	/**
	 * 配置文件
	 * @author SiaoLeon
	 */
	public class Config
	{
		// -------------------------------------------------------------------------------------------------------- 静态常量
		
		// -------------------------------------------------------------------------------------------------------- 静态变量
		
		// -------------------------------------------------------------------------------------------------------- 静态方法
		
		// -------------------------------------------------------------------------------------------------------- 静态函数
		
		// -------------------------------------------------------------------------------------------------------- 属性
		
		private var _xml:XML;
		
		/**
		 * XML
		 * @return
		 */
		public function get xml():XML
		{
			return this._xml;
		}
		
		private var _name:String;
		
		/**
		 * 名称
		 * @return
		 */
		public function get name():String
		{
			return this._name;
		}
		
		// -------------------------------------------------------------------------------------------------------- 变量
		
		/**
		 * 属性
		 * @default
		 */
		protected var attributes:HashMap = new HashMap();
		
		/**
		 * 选项
		 * @default
		 */
		protected var options:HashMap = new HashMap();
		
		// -------------------------------------------------------------------------------------------------------- 构造
		
		/**
		 * 构造函数
		 */
		public function Config(xml:XML=null)
		{
			this._name = xml.name();
			this._xml = xml;
			
			for each (var attribute:XML in xml.attributes())
			{
				this.attributes.put((attribute.name() as QName).localName, attribute.toString());
			}
			
			for (var i:int = 0; i < xml.children().length(); i++)
			{
				var option:XmlValue = new XmlValue(new XML(xml.child(i)));
				this.options.put(option.name, option);
			}
		}
		
		// -------------------------------------------------------------------------------------------------------- 方法
		
		/**
		 * 获取属性
		 * @param name 属性名称
		 * @return
		 */
		public function attribute(name:String):String
		{
			return this.attributes.getValue(name);
		}
		
		/**
		 * 获取选项列表
		 * @param attribute 属性名称，当设定该参数时将只获取属性为value参数的选项
		 * @param value 属性匹配值
		 * @return
		 */
		public function getOptions(attribute:String=null, value:Object=null):Vector.<XmlValue>
		{
			var list:Vector.<XmlValue> = new Vector.<XmlValue>();
			
			for each (var option:XmlValue in this.options.values)
			{
				if (attribute == null || value == null || option.attribute(attribute) == value)
				{
					list.push(option);
				}
			}
			
			return list;
		}
		
		/**
		 * 绑定到静态类
		 * @param classFile 包含静态属性的配置类（每个属性由静态变量定义）
		 */
		public function bind(classFile:Class):void
		{
			var meta:XML = describeType(classFile);
			
			for each (var attribute:XML in meta.elements("variable"))
			{
				if (this.options.containsKey(String(attribute.@name)))
				{
					var value:* = (this.options.getValue(String(attribute.@name)) as XmlValue).value;
					
					try
					{
						classFile[attribute.@name] = Json.decode(value);
					}
					catch (err:Error)
					{
						classFile[attribute.@name] = value;
					}
				}
			}
		}
		
		/**
		 * 获取选项
		 * @param name 选项名称
		 * @return
		 */
		public function getOption(name:String):XmlValue
		{
			return this.options.getValue(name) as XmlValue;
		}
		
		/**
		 * 获取选项值
		 * @param name 选项名称
		 * @return
		 */
		public function getValue(name:String):*
		{
			return (this.options.getValue(name) as XmlValue).value;
		}
		
		/**
		 * 获取字符串
		 * @param name 选项名称
		 * @return
		 */
		public function getString(name:String):String
		{
			return String((this.options.getValue(name) as XmlValue).value);
		}
		
		/**
		 * 获取布尔值
		 * @param name 选项名称
		 * @return
		 */
		public function getBoolean(name:String):Boolean
		{
			var value:* = (this.options.getValue(name) as XmlValue).value;
			
			try
			{
				return Boolean(Json.decode(value));
			}
			catch (err:Error)
			{
				return Boolean(value);
			}
		}
		
		/**
		 * 获取数字
		 * @param name 选项名称
		 * @return
		 */
		public function getNumber(name:String):Number
		{
			return Number((this.options.getValue(name) as XmlValue).value);
		}
		
		/**
		 * 获取JSON对象
		 * @param name 选项名称
		 * @return
		 */
		public function getObject(name:String):Object
		{
			try
			{
				return Json.decode(String((this.options.getValue(name) as XmlValue).value));
			}
			catch (err:Error)
			{
				return null;
			}
		}
		
		/**
		 * 获取XML对象
		 * @param name 选项名称
		 * @return
		 */
		public function getXML(name:String):XML
		{
			try
			{
				return (this.options.getValue(name) as XmlValue).xml;
			}
			catch (err:Error)
			{
				return null;
			}
		}
	
		// -------------------------------------------------------------------------------------------------------- 函数
	
	}
}
